#ifndef CCOLOR_H
#define CCOLOR_H
// Copyright (C) 2002 IFOnlyRT Project.

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License 2.0 for more details.

// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/

// Official SVN repository and contact information can be found at
// http://code.google.com/p/ifonlyrt/

/*
 * CColor.hpp
 *
 *  Created on: 16 oct. 2009
 *      Author: Maxime Gaudin
 */
#include <iostream>
#include <string>

#ifndef UINT
	#define UINT
	typedef unsigned int uint;
#endif

/**
 * Classe conteneur de couleurs.
 */
class CColor {
	public:
		/**
		 * Couleur Noire
		 * : (0, 0, 0)
		 */
		static const CColor Black;

		/**
		 * Couleur Blanche
		 * : (1, 1, 1)
		 */
		static const CColor White;

		/**
		 * Couleur Rouge
		 * : (1, 0, 0)
		 */
		static const CColor Red;

		/**
		 * Couleur Verte
		 * : (0, 1, 0)
		 */
		static const CColor Green;

		/**
		 * Couleur Bleue
		 * : (0, 0, 1)
		 */
		static const CColor Blue;

	public:
		/**
		 * Constructeur de CColor non initialisé
		 * (0, 0, 0)
		 */
		CColor();

		/**
		 * Constructeur de CColor Initialisé
		 * @param R = Composante Rouge
		 * @param G = Composante Verte
		 * @param B = Composante Bleue
		 */
		CColor(const double R, const double G, const double B);

		/**
		 * Constructeur de CColor Initialisé
		 * @param Value = Composante R, G, et B
		 */
		CColor(const double Value);

		/**
		 * Constructeur de copie
		 * @param C2 = Couleur à copier
		 */
		CColor(const CColor& C2);

	public:
		/**
		 * Clampe les valeurs de R, G et B entre 0 et 1
		 */
		void Saturate();

	public:
		/**
		 * Opérateur =
		 * : Opérateur d'affectation
		 */
		CColor operator =(const CColor& C2);

		/**
		 * Opérateur []
		 * : [0] = R, [1] = G, [2] = B
		 */
		double operator [](const uint i) const;

		/**
		 * Operateur +
		 * : Ajoute membre à membre deux CColor
		 */
		CColor operator +(const CColor& C2);

		/**
		 * Opérateur +=
		 * : Ajoute membre à membre deux CColor
		 */
		CColor operator +=(const CColor& C2);

		/**
		 * Soustrait +
		 * : Ajoute membre à membre deux CColor
		 */
		CColor operator -(const CColor& C2);

		/**
		 * Opérateur +=
		 * : Soustrait membre à membre deux CColor
		 */
		CColor operator -=(const CColor& C2);

		/**
		 * Opérateur *
		 * : Multiplie membre à membre une couleur par un scalaire
		 */
		CColor operator *(const double Scalar);

		/**
		 * Opérateur *=
		 * : Multiplie membre à membre une couleur par un scalaire
		 */
		CColor operator *=(const double Scalar);

		/**
		 * Opérateur /
		 * : Divise membre à membre une couleur par un scalaire
		 */
		CColor operator /(const double Scalar);

		/**
		 * Opérateur /=
		 * : Divise membre à membre une couleur par un scalaire
		 */
		CColor operator /=(const double Scalar);

		/**
		 * Opérateur *
		 * : Module deux CColor
		 */
		CColor operator *(const CColor& C2);

		/**
		 * Opérateur *=
		 * : Module deux CColor
		 */
		CColor operator *=(const CColor& C2);

	public:
		/**
		 * Composante Rouge de la couleur
		 */
		double R;

		/**
		 * Composante Verte de la couleur
		 */
		double G;

		/**
		 * Composante Bleue de la couleur.
		 */
		double B;
};

inline bool operator ==(const CColor& C1, const CColor& C2)
{
	if(C1.R != C2.R) return false;
	if(C1.G != C2.G) return false;
	if(C1.B != C2.B) return false;

	return true;
}

inline bool operator !=(const CColor& C1, const CColor& C2)
{ return !(C1 == C2); }

inline std::ostream& operator <<(std::ostream& outStream,const CColor& C1)
{
	outStream << std::string("{R = ");
	outStream << C1.R << ", G = ";
	outStream << C1.G << ", B = ";
	outStream << C1.B << "}";
	return outStream;
}
#endif /* CCOLOR_H_ */
